package org.gcb.core.model;

import java.util.HashSet;
import java.util.Set;
import javax.swing.event.SwingPropertyChangeSupport;
import org.gcb.core.model.util.Utilities;

/**
 *
 * @author Jason
 */
public class Skill {
    public static final String PROP_DESCRIPTION = "description";
    public static final String PROP_TRAINED = "trained";
    public static final String PROP_MODIFIERS = "modifiers";
    private final AbilityType defaultCoreAbility;
    private final String text;
    private final Toon toon;
    private final Boolean armorPenalty;
    private String description = "[None]";
    private Boolean trained = false;
    //TODO may need to make modifiers an actual class to enable value binding
    private Set<MiscModifier<?, Integer>> modifiers = new HashSet<MiscModifier<?, Integer>>(0);
    private SwingPropertyChangeSupport propSupport = new SwingPropertyChangeSupport(this, true);

    public Skill(AbilityType defaultCoreAbility, String text, Toon toon, Boolean armorPenalty) {
        this.defaultCoreAbility = defaultCoreAbility;
        this.text = text;
        this.toon = toon;
        this.armorPenalty = armorPenalty;
    }

    public Skill(AbilityType defaultCoreAbility, String text, Toon toon, Boolean armorPenalty, Boolean trained) {
        this.defaultCoreAbility = defaultCoreAbility;
        this.text = text;
        this.toon = toon;
        this.armorPenalty = armorPenalty;
        this.trained = trained;
    }

    public Skill(AbilityType defaultCoreAbility, String text, String description, Toon toon, Boolean armorPenalty, Boolean trained) {
        this.defaultCoreAbility = defaultCoreAbility;
        this.text = text;
        this.description = description;
        this.toon = toon;
        this.armorPenalty = armorPenalty;
        this.trained = trained;
    }

    public Skill(AbilityType defaultCoreAbility, String text, String description, Toon toon, Boolean armorPenalty) {
        this.defaultCoreAbility = defaultCoreAbility;
        this.text = text;
        this.description = description;
        this.toon = toon;
        this.armorPenalty = armorPenalty;
    }

    public Skill(AbilityType defaultCoreAbility, String text, String description, Toon toon, Boolean trained, Boolean armorPenalty, Set<MiscModifier<?, Integer>> modifiers) {
        this.defaultCoreAbility = defaultCoreAbility;
        this.text = text;
        this.description = description;
        this.toon = toon;
        this.trained = trained;
        this.armorPenalty = armorPenalty;
        this.modifiers = modifiers;
    }

    public Boolean getArmorPenalty() {
        return armorPenalty;
    }

    public AbilityType getDefaultCoreAbility() {
        return defaultCoreAbility;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        String oldDescription = this.description;
        this.description = description;
        propSupport.firePropertyChange(PROP_DESCRIPTION, oldDescription, this.description);
    }

    public Set<MiscModifier<?, Integer>> getModifiers() {
        return modifiers;
    }

    public void setModifiers(Set<MiscModifier<?, Integer>> modifiers) {
        Set<MiscModifier<?, Integer>> oldModifiers = this.modifiers;
        this.modifiers = modifiers;
        propSupport.firePropertyChange(PROP_MODIFIERS, oldModifiers, this.modifiers);
    }

    public String getText() {
        return text;
    }

    public Toon getToon() {
        return toon;
    }

    public Boolean getTrained() {
        return trained;
    }

    public void setTrained(Boolean trained) {
        Boolean oldTrained = this.trained;
        this.trained = trained;
        propSupport.firePropertyChange(PROP_TRAINED, oldTrained, trained);
    }

    public Integer getModifier() {
        Integer halfLvl = toon.getLevel()/2;
        Integer abilityModifier = toon.getAbilities().get(defaultCoreAbility).getModifier();
        Integer trainedBonus = trained?5:0;
        Integer racial = 0;//TODO to be implemented
        Integer miscMod = 0;//Utilities.calculateMiscModifier(modifiers);
        Integer armorPenaltyValue = armorPenalty?toon.getEquipment().getWorn().getCheckPenalty():0;
        return halfLvl + abilityModifier + trainedBonus + racial + miscMod - armorPenaltyValue;
    }
}
